/**
 * 
 */
package it.unical.canonaco.rende.igpe.game.cbv.guilayer.mainmenu;

import it.unical.canonaco.rende.igpe.game.cbv.guilayer.AnimatedPanel;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.MainFrame;
import it.unical.canonaco.rende.igpe.game.cbv.guilayer.components.OverallGUILayoutFactory;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.filehandlers.IniLoader;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.prefs.BackingStoreException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.MenuSelectionManager;
import javax.swing.Scrollable;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;

import test.MassimoDialog;

/**
 * @author Massimo Canonaco
 *
 */
public class MainMenuPanel extends AnimatedPanel 
{
	/** */
	static private final String CONFIG_FILE = "cbvapps"+File.separator+"uiresource"+File.separator+"mainschema.ini";
	
	static public final String MAIN_MENU_PANEL_NAME = "mainMenuPanel";
	
	/** */
	static private final int BUTTON_MARGIN_SPACE = 4;
	
	/** */
	private	PlayerInfoDailog pid;
	
	/** */
	private	LoadProfileDialog pad;
	
	/**It's the component on which this panel is contained. */
	private MainFrame parentMainFrame;
	
	/**It's the layout manager of the panel. */
	private SpringLayout layout;
	
	/** */
	private ActionEventMenuSelectionManager buttonBehavior;

	/** */
	private Color backgroundColor;
	
	/** */
	private Image clouds;
	
	/** */
	private List<Cloud> cloudsList;
	
//	/** */
//	Thread t;
	private Map<String, String>infoMap;
	/** */
	public MainMenuPanel(final MainFrame parent)
	{
		super(55,CONFIG_FILE);
		this.parentMainFrame = parent;
	}

	/** */
	private JPanel getMenu(Map infoMap, OverallGUILayoutFactory factory)
	{
		buttonBehavior = new ActionEventMenuSelectionManager(KeyEvent.VK_UP, KeyEvent.VK_DOWN, KeyEvent.VK_ENTER);
//		waitCall = 55;
//		lastCall = System.currentTimeMillis();
		
		try {
			pid = new CreatePlayerProfileDialog(this, infoMap, factory);
			pad = new LoadProfileDialog(this, infoMap, factory);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//------
		JPanel menuSelection = new JPanel();
		
		String MENU_BUTTON_SIZE_WIDTH = "menubutton.width",
				MENU_BUTTON_SIZE_HEIGHT = "menubutton.height",
				MENU_BUTTON_SIZE_TEXT = "menubutton.text.size";
		
		int buttonWidth = Integer.parseInt((String) infoMap.get(MENU_BUTTON_SIZE_WIDTH)), 
				buttonHeight = Integer.parseInt((String) infoMap.get(MENU_BUTTON_SIZE_HEIGHT));
		
		float textSize = Float.parseFloat((String) infoMap.get(MENU_BUTTON_SIZE_TEXT));
		
		//TODO: cambiare i label dei bottoni in modo da fare l'internaziolicoso
		JButton newGame = getButton(textSize, "Nuovo", buttonWidth, buttonHeight, factory),
				continueGame = getButton(textSize,"Carica", buttonWidth, buttonHeight, factory),
				option = getButton(textSize,"Opzioni", buttonWidth, buttonHeight, factory),
				exit = getButton(textSize, "Esci", buttonWidth, buttonHeight, factory);
		
		GridBagConstraints menuSelectionConst = new GridBagConstraints();
		GridBagLayout menuSelectionLayout = new GridBagLayout();
		
		menuSelectionConst.fill = GridBagConstraints.NONE;
		menuSelectionConst.weightx = 0;
		menuSelectionConst.weighty = 0;
		menuSelectionConst.gridx = 0;
		menuSelectionConst.insets = new Insets(BUTTON_MARGIN_SPACE, 0, BUTTON_MARGIN_SPACE, 0);
		menuSelectionConst.gridy = GridBagConstraints.RELATIVE;
		
		menuSelection.setLayout(menuSelectionLayout);
		menuSelection.setOpaque(false);
		
		//DEBUG
		JButton crealivelloprovra = getButton(textSize, "crea", buttonWidth, buttonHeight, factory);
		crealivelloprovra.setEnabled(false);
		menuSelection.add(newGame,menuSelectionConst);
		menuSelection.add(continueGame,menuSelectionConst);
//		menuSelection.add(option,menuSelectionConst);
		menuSelection.add(exit,menuSelectionConst);
		
		newGame.addActionListener(new AA(this,factory,infoMap) {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				pid.showDialog(parentMainFrame, "cic");
			}
		});
		
		continueGame.addActionListener(new AA(this,factory,infoMap) {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				pad.showDialog(parentMainFrame, "cic");
			}
		});
		exit.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});
		
//		menuSelection.add(crealivelloprovra,menuSelectionConst); //TODO: creare realmente questo bottone e spostarlo in alto rispetto esci.
		
		int totalHeight = (buttonHeight+menuSelectionConst.insets.top+menuSelectionConst.insets.bottom)*5;
		menuSelection.setSize(buttonWidth, totalHeight);
		menuSelection.setPreferredSize(new Dimension(buttonWidth, totalHeight));
		
		menuSelection.setName("nome menu selection");
		return menuSelection;
	}
	/** */
	private void coordinateComponents(JLabel logo, JLabel backBackgroundImage, JLabel backgroundMenu, JPanel menuSelection, JLayeredPane p)
	{
		
		final int logoHeight = logo.getHeight(),
				backgroundMenuHeight = backgroundMenu.getHeight(),
				buttonSpring = (backgroundMenuHeight -100 - menuSelection.getHeight())/2 +100;
			
		layout = new SpringLayout();
		setLayout(layout);
				
		Spring spring = Spring.constant(this.getWidth()/2);
		layout.putConstraint(SpringLayout.WEST, logo, spring, SpringLayout.WEST, this);
		layout.putConstraint(SpringLayout.EAST, logo, spring, SpringLayout.EAST, this);
		
		layout.putConstraint(SpringLayout.WEST, backBackgroundImage, spring, SpringLayout.WEST, this);
		layout.putConstraint(SpringLayout.EAST, backBackgroundImage, spring, SpringLayout.EAST, this);

		layout.putConstraint(SpringLayout.WEST, menuSelection, spring, SpringLayout.WEST, this);
		layout.putConstraint(SpringLayout.EAST, menuSelection, spring, SpringLayout.EAST, this);
		
		spring = Spring.constant(0, logoHeight, this.getHeight());
		layout.putConstraint(SpringLayout.NORTH, backBackgroundImage, spring, SpringLayout.NORTH, this);
		
		spring = Spring.constant(this.getWidth()/2 - 50);
		layout.putConstraint(SpringLayout.WEST, backgroundMenu, spring, SpringLayout.WEST, this);
		layout.putConstraint(SpringLayout.EAST, backgroundMenu, spring, SpringLayout.EAST, this);
		
		spring = Spring.constant(0);
		layout.putConstraint(SpringLayout.SOUTH, backgroundMenu, spring, SpringLayout.SOUTH, backBackgroundImage);
	
		spring = Spring.constant(0, buttonSpring, buttonSpring);
		layout.putConstraint(SpringLayout.NORTH, menuSelection, spring, SpringLayout.NORTH, backgroundMenu);
	}
//	
	JButton getButton(float lsize, String label, int width,int height, OverallGUILayoutFactory factory)
	{
		JButton button = factory.createButton(lsize, label, width, height);
		button.addFocusListener(buttonBehavior);
		button.addKeyListener(buttonBehavior);
		button.addMouseMotionListener(buttonBehavior);
		button.setPreferredSize(new Dimension(width, height));
		button.setSize(width, height);
		return button;
	}

	/**
	 * @return the parentMainFrame
	 */
	public MainFrame getParentMainFrame() 
	{
		return parentMainFrame;
	}
	
	/** */
	private abstract class AA implements ActionListener{
		Map infoMap;
		OverallGUILayoutFactory factory;
		MainMenuPanel mmp;
		public AA(MainMenuPanel mmp, OverallGUILayoutFactory factory, Map infoMap)
		{
			this.infoMap = infoMap;
			this.mmp = mmp;
			this.factory = factory;
		}
		@Override
		public abstract void actionPerformed(ActionEvent e);
		
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		if(isReady())
		{
			Graphics2D g2 = (Graphics2D)g;
			for (Cloud c : cloudsList) 
			{
				g2.drawImage(clouds,c.xPos, c.yPos, clouds.getWidth(null), clouds.getHeight(null),null);
			}
		}
	}
	
	
	private class Cloud{
		private int xPos;
		private int yPos;
		
		private void nextStep(int a, int b)
		{
			xPos--;
			xPos = xPos % a;
//			System.out.println(xPos);
			if(xPos+b == 0)
			{
				xPos = a-1;
			}
//			if(xPos < 0)
//				xPos = Math.abs(xPos);
		}
	}

	@Override
	protected void updateScene() {
		for (Cloud c : cloudsList) 
		{
			c.nextStep(1366,768);
		}
		
	}

	@Override
	protected void load(final String from) {
		IniLoader loader = new IniLoader(new HashMap<String,String>());
		try {
			loader.load(from);
		} catch (IOException e) 
		{
			e.printStackTrace();
		}
		infoMap = loader.getContents();
		cloudsList = new LinkedList<>();	
//		setLayout(layout);
	}

	@Override
	protected void settingScene() 
	{
		final String PANEL_BACKGROUND_COLOR = "menubackground.overall.color",
				PANEL_BACKGROUND_IMAGE = "menubackground.overall.path",
				PANEL_BACKGROUND_IMAGE_WIDTH = "menubackground.overall.width",
				PANEL_BACKGROUND_IMAGE_HEIGHT = "menubackground.overall.height",
				MENU_LOGO = "menulogo.path",
				MENU_LOGO_WIDTH = "menulogo.width",
				MENU_LOGO_HEIGHT = "menulogo.height",
				MENU_SELECTION_BACKGROUND = "menubackground.selection.path",
				MENU_SELECTION_WIDTH = "menubackground.selection.width",
				MENU_SELECTION_HEIGHT = "menubackground.selection.height",
				CLOUDS = "menubackground.overall.cloud",
				CLOUDS_NUMBER = "menubackground.overall.clouds";

		OverallGUILayoutFactory factory = OverallGUILayoutFactory.getInstance();

		setBackground(factory.getParsedColor((String)infoMap.get(PANEL_BACKGROUND_COLOR)));
//		backgroundColor = factory.getParsedColor((String)infoMap.get(PANEL_BACKGROUND_COLOR));
		clouds = (new ImageIcon((String)infoMap.get(CLOUDS))).getImage();

		Random random = new Random(0);
		cloudsList = new LinkedList<>();
		int cloudsNumber = Integer.parseInt((String)infoMap.get(CLOUDS_NUMBER));

		Cloud c = null;
		for(int index = 0; index < cloudsNumber; index++)
		{
			c = new Cloud();
			c.xPos = random.nextInt(1366);
			c.yPos = random.nextInt(768);
			cloudsList.add(c);
		}
		//setPreferredSize(new Dimension(1366, 768));
		setLayout(layout);
		JLabel logo = new JLabel(new ImageIcon((String)infoMap.get(MENU_LOGO)));
		logo.setSize(factory.getParsedDimension((String)infoMap.get(MENU_LOGO_WIDTH), (String)infoMap.get(MENU_LOGO_HEIGHT)));
		logo.setPreferredSize(factory.getParsedDimension((String)infoMap.get(MENU_LOGO_WIDTH), (String)infoMap.get(MENU_LOGO_HEIGHT)));
		logo.setMaximumSize(factory.getParsedDimension((String)infoMap.get(MENU_LOGO_WIDTH), (String)infoMap.get(MENU_LOGO_HEIGHT)));
		//logo.setOpaque(false);
		JLabel backBackgroundImage = new JLabel(new ImageIcon((String)infoMap.get(PANEL_BACKGROUND_IMAGE)));
		//backBackgroundImage.setOpaque(false);
		backBackgroundImage.setSize(factory.getParsedDimension((String)infoMap.get(PANEL_BACKGROUND_IMAGE_WIDTH), (String)infoMap.get(PANEL_BACKGROUND_IMAGE_HEIGHT)));
		JLabel backgroundMenu = new JLabel(new ImageIcon((String)infoMap.get(MENU_SELECTION_BACKGROUND)));
		backgroundMenu.setSize(factory.getParsedDimension((String)infoMap.get(MENU_SELECTION_WIDTH), (String)infoMap.get(MENU_SELECTION_HEIGHT)));
		//backgroundMenu.setOpaque(false);
		JPanel menuSelection = getMenu(infoMap, factory);
		//menuSelection.setOpaque(false);

		this.add(menuSelection);
		this.add(logo);
		this.add(backgroundMenu);
		this.add(backBackgroundImage);
		//this.add(logo,DEFAULT_LAYER);
		coordinateComponents(logo, backBackgroundImage, backgroundMenu, menuSelection, null);
		//this.add(backBackgroundImage);
	}
}
